package com.yypx.action;

import java.io.File;
import java.io.PrintWriter;
import java.util.Properties;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.jcs.JCS;
import org.apache.jcs.access.exception.CacheException;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.yypx.common.utils.ObjectUtil;

@Scope("prototype")
@Component("menuAction")
public class MenuAction extends BaseAction {

	private static final long serialVersionUID = 1L;
	private static final Log logger = LogFactory.getLog(MenuAction.class);
	private static final String CACHE_KEY_SUBMENU_MODULE = "Menu_SubMenu_xml_%1$s";
	private static final String CACHE_KEY_SECONDTOPMENU_MODULE = "Menu_SecondMenu_xml_%1$s";
	private static JCS menuCache;
	static {
		try {
			menuCache = JCS.getInstance("MenuActionCache");
		} catch (CacheException e) {
			logger.error(e);
			menuCache = null;
		}
	}

	public void clearCache() {
		if (menuCache != null)
			try {
				menuCache.clear();
			} catch (CacheException e) {
				logger.error("清缓存失败");
			}
	}

	private Object getCacheByKey(String key) {
		Object obj = null;
		if (menuCache != null) {
			obj = menuCache.get(key);
		}
		return obj;
	}

	private void setCacheByKey(String key, Object obj) {
		try {
			if (menuCache != null)
				menuCache.put(key, obj);
		} catch (CacheException e) {
			logger.error(e);
		}
	}

	public void getTop() throws Exception {
		try {
			String pageLevel = getRequest().getAttribute("pagelevel").toString();
			TransformerFactory tFactory = TransformerFactory.newInstance();
			// xsl file cache
			String topmenuxslcache = "Menu_TopMenu_xsl";
			Document xslDocument = (Document) getCacheByKey(topmenuxslcache);
			if (xslDocument == null) {
				xslDocument = com.yypx.common.utils.XMLUtil.getXSLDocument(new File(getRequest().getSession().getServletContext().getRealPath("/") + "cnf/topmenu.xsl"));
				setCacheByKey(topmenuxslcache, xslDocument);
			}
			DOMSource source = new DOMSource(xslDocument);
			// xsl file cache
			Transformer tx = tFactory.newTransformer(source);
			Properties properties = tx.getOutputProperties();
			properties.setProperty(OutputKeys.ENCODING, "utf-8");
			properties.setProperty(OutputKeys.METHOD, "html");
			tx.setOutputProperties(properties);
			// xml file cache
			String topmenuxmlcache = "Menu_TopMenu_xml";
			Document xmlDocument = (Document) getCacheByKey(topmenuxmlcache);
			if (xmlDocument == null) {
				xmlDocument = com.yypx.common.utils.XMLUtil.getDocument(new File(getRequest().getSession().getServletContext().getRealPath("/") + "cnf/topmenu.xml"));
				// 增加I18N
				NodeList nl = xmlDocument.getElementsByTagName("menu");
				for (int i = 0; i < nl.getLength(); i++) {
					NodeList nList = nl.item(i).getChildNodes();
					for (int j = 0; j < nList.getLength(); j++) {
						Node node = nList.item(j);
						if (node.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE && node.getNodeName().equals("text")) {
							node.setTextContent(getText("TopMenu.text." + node.getTextContent()));
						}
						if (node.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE && node.getNodeName().equals("describe")) {
							node.setTextContent(getText("TopMenu.describe." + node.getTextContent()));
						}
					}
				}
				// 增加I18N
				setCacheByKey(topmenuxmlcache, xmlDocument);
			}
			Document leveladdedxmlDocument = null;
			leveladdedxmlDocument = (Document) ObjectUtil.copy(xmlDocument);
			// 增加相对路径
			NodeList nl = leveladdedxmlDocument.getElementsByTagName("menu");
			for (int i = 0; i < nl.getLength(); i++) {
				NodeList nList = nl.item(i).getChildNodes();
				for (int j = 0; j < nList.getLength(); j++) {
					Node node = nList.item(j);
					if (node.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE && node.getNodeName().equals("url")) {
						if (node.getTextContent().startsWith("http:") || node.getTextContent().startsWith("https:")) {
							node.setTextContent(node.getTextContent());
						}
						else
							node.setTextContent(pageLevel + node.getTextContent());
					}
				}
			}
			// 增加相对路径
			// xml file cache
			HttpServletResponse response = getResponse();
			response.setContentType("text/html;charset=utf-8");
			response.setCharacterEncoding("utf-8");
			PrintWriter pw = response.getWriter();
			tx.transform(new DOMSource(leveladdedxmlDocument), new StreamResult(pw));
		} catch (Exception e) {
			LOG.error("顶层菜单载入失败。" + e.getMessage());
		}
	}

	public void getSub() throws Exception {
		try {
			String pageLevel = getRequest().getAttribute("pagelevel").toString();
			String currentModule = getRequest().getAttribute("submodulefile").toString();
			File xmlFile = new File(getRequest().getSession().getServletContext().getRealPath("/") + "cnf/" + currentModule + "Module.xml");
			if (xmlFile.exists()) {
				TransformerFactory tFactory = TransformerFactory.newInstance();
				// xsl file cache
				String submenuxslcache = "Menu_SubMenu_xsl";
				Document xslDocument = (Document) getCacheByKey(submenuxslcache);
				if (xslDocument == null) {
					xslDocument = com.yypx.common.utils.XMLUtil.getXSLDocument(new File(getRequest().getSession().getServletContext().getRealPath("/") + "cnf/submenu.xsl"));
					setCacheByKey(submenuxslcache, xslDocument);
				}
				DOMSource source = new DOMSource(xslDocument);
				// xsl file cache
				Transformer tx = tFactory.newTransformer(source);
				Properties properties = tx.getOutputProperties();
				properties.setProperty(OutputKeys.ENCODING, "utf-8");
				properties.setProperty(OutputKeys.METHOD, "html");
				tx.setOutputProperties(properties);
				// xml file cache
				String submenuxmlcache = String.format(CACHE_KEY_SUBMENU_MODULE, currentModule);
				Document xmlDocument = (Document) getCacheByKey(submenuxmlcache);
				if (xmlDocument == null) {
					xmlDocument = com.yypx.common.utils.XMLUtil.getDocument(xmlFile);
					// 增加I18N
					NodeList nl = xmlDocument.getElementsByTagName("menu");
					for (int i = 0; i < nl.getLength(); i++) {
						NodeList nList = nl.item(i).getChildNodes();
						String currentSubModule = "";
						for (int j = 0; j < nList.getLength(); j++) {
							Node node = nList.item(j);
							if (node.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE && node.getNodeName().equals("submodule")) {
								currentSubModule = node.getTextContent();
							}
							if (node.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE && node.getNodeName().equals("text")) {
								node.setTextContent(getText("SubMenu." + currentModule + ".text." + node.getTextContent()));
							}
							if (node.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE && node.getNodeName().equals("describe")) {
								node.setTextContent(getText("SubMenu." + currentModule + ".describe." + node.getTextContent()));
							}
							if (node.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE && node.getNodeName().equals("submenu")) {
								NodeList subnl = node.getChildNodes();
								for (int k = 0; k < subnl.getLength(); k++) {
									Node subNode = subnl.item(k);
									if (subNode.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE && subNode.getNodeName().equals("text")) {
										subNode.setTextContent(getText("SubMenu." + currentModule + ".text." + currentSubModule + "." + subNode.getTextContent()));
									}
									if (subNode.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE && subNode.getNodeName().equals("describe")) {
										subNode.setTextContent(getText("SubMenu." + currentModule + ".describe." + currentSubModule + "." + subNode.getTextContent()));
									}
								}
							}
						}
					}
					// 增加I18N
					setCacheByKey(submenuxmlcache, xmlDocument);
				}
				Document leveladdedxmlDocument = null;
				leveladdedxmlDocument = (Document) ObjectUtil.copy(xmlDocument);
				// 增加相对路径
				NodeList nl = leveladdedxmlDocument.getElementsByTagName("menu");
				for (int i = 0; i < nl.getLength(); i++) {
					NodeList nList = nl.item(i).getChildNodes();
					for (int j = 0; j < nList.getLength(); j++) {
						Node node = nList.item(j);
						if (node.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE && node.getNodeName().equals("submenu")) {
							NodeList subnl = node.getChildNodes();
							for (int k = 0; k < subnl.getLength(); k++) {
								Node subNode = subnl.item(k);
								if (subNode.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE && subNode.getNodeName().equals("url")) {
									if (subNode.getTextContent().startsWith("javascript:")) {
										subNode.setTextContent(subNode.getTextContent());
									} else {
										// subNode.setTextContent(pageLevel +
										// subNode.getTextContent());
										// 采购工作夹，左侧菜单需带参数
										subNode.setTextContent(pageLevel + handleSpecialModuleMenu(currentModule, subNode.getTextContent()));
									}
									// 左侧子菜单增加随机数
									if (subNode.getTextContent().contains("?")) {
										subNode.setTextContent(subNode.getTextContent() + "&rd_menu=" + Math.random());
									} else {
										subNode.setTextContent(subNode.getTextContent() + "?rd_menu=" + Math.random());
									}
								}
							}
						}
					}
				}
				// 增加相对路径
				HttpServletResponse response = getResponse();
				response.setContentType("text/html;charset=utf-8");
				response.setCharacterEncoding("utf-8");
				PrintWriter pw = response.getWriter();
				// tx.transform(xmlSource, new StreamResult(pw));
				tx.transform(new DOMSource(leveladdedxmlDocument), new StreamResult(pw));
			}
		} catch (Exception e) {
			LOG.error("左侧子菜单载入失败。" + e.getMessage());
		}
	}

	/**
	 * 载入二级顶层菜单
	 * 
	 * @throws Exception
	 */
	public void getSecond() throws Exception {
		try {
			String currentModule = getRequest().getAttribute("module").toString();
			File xmlFile = new File(getRequest().getSession().getServletContext().getRealPath("/") + "cnf/" + currentModule + "SecondTop.xml");
			if (xmlFile.exists()) {
				String pageLevel = getRequest().getAttribute("pagelevel").toString();
				TransformerFactory tFactory = TransformerFactory.newInstance();
				// xsl file cache
				String topmenuxslcache = "Menu_SecondTopMenu_xsl";
				Document xslDocument = (Document) getCacheByKey(topmenuxslcache);
				if (xslDocument == null) {
					xslDocument = com.yypx.common.utils.XMLUtil.getXSLDocument(new File(getRequest().getSession().getServletContext().getRealPath("/") + "cnf/secondtopmenu.xsl"));
					setCacheByKey(topmenuxslcache, xslDocument);
				}
				DOMSource source = new DOMSource(xslDocument);
				// xsl file cache
				Transformer tx = tFactory.newTransformer(source);
				Properties properties = tx.getOutputProperties();
				properties.setProperty(OutputKeys.ENCODING, "utf-8");
				properties.setProperty(OutputKeys.METHOD, "html");
				tx.setOutputProperties(properties);
				// xml file cache
				String secondtopmenuxmlcache = String.format(CACHE_KEY_SECONDTOPMENU_MODULE, currentModule);
				Document xmlDocument = (Document) getCacheByKey(secondtopmenuxmlcache);
				if (xmlDocument == null) {
					xmlDocument = com.yypx.common.utils.XMLUtil.getDocument(xmlFile);
					// 增加I18N
					NodeList nl = xmlDocument.getElementsByTagName("menu");
					for (int i = 0; i < nl.getLength(); i++) {
						NodeList nList = nl.item(i).getChildNodes();
						for (int j = 0; j < nList.getLength(); j++) {
							Node node = nList.item(j);
							if (node.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE && node.getNodeName().equals("text")) {
								node.setTextContent(getText("SecondMenu.text." + currentModule + "." + node.getTextContent()));
							}
							if (node.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE && node.getNodeName().equals("describe")) {
								node.setTextContent(getText("SecondMenu.describe." + currentModule + "." + node.getTextContent()));
							}
						}
					}
					// 增加I18N
					setCacheByKey(secondtopmenuxmlcache, xmlDocument);
				}
				Document leveladdedxmlDocument = null;
				leveladdedxmlDocument = (Document) ObjectUtil.copy(xmlDocument);
				// 增加相对路径
				NodeList nl = leveladdedxmlDocument.getElementsByTagName("menu");
				for (int i = 0; i < nl.getLength(); i++) {
					NodeList nList = nl.item(i).getChildNodes();
					for (int j = 0; j < nList.getLength(); j++) {
						Node node = nList.item(j);
						if (node.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE && node.getNodeName().equals("url")) {
							node.setTextContent(pageLevel + handleSpecialModuleMenu(currentModule, node.getTextContent()));
						}
					}
				}
				// 增加相对路径
				// xml file cache
				HttpServletResponse response = getResponse();
				response.setContentType("text/html;charset=utf-8");
				response.setCharacterEncoding("utf-8");
				PrintWriter pw = response.getWriter();
				tx.transform(new DOMSource(leveladdedxmlDocument), new StreamResult(pw));
			}
		} catch (Exception e) {
			LOG.error("二级顶层菜单载入失败。" + e.getMessage());
		}
	}

	private String handleSpecialModuleMenu(String module, String url) {
		return url;
	}

	public void setCookie() {
		String displaysubmenu = getRequest().getParameter("displaysubmenu");
		Cookie cookie = new Cookie("showleftmenu", displaysubmenu);
		cookie.setPath("/");
		getResponse().addCookie(cookie);
	}

	/*
	 * add by lwm 为了防止其他页面有action errors传递时，使得本action不执行的问题
	 */
	/*
	 * (non-Javadoc)
	 * 
	 * @see com.opensymphony.xwork2.ActionSupport#validate()
	 */
	public void validate() {
		this.clearErrorsAndMessages();
	}
}